package engine.graphics.popup;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

import engine.data.Map;
import engine.data.Player;
import engine.data.TerrainType;
import engine.data.Tile;
import engine.graphics.MapCanvas;
import engine.graphics.MapCanvasEngine;
import engine.graphics.misc.GraphicsCustomFont;

public final class PopupMap extends Popup {

	private static final int TERRAIN_COLOR = 0x70b850;

	// TODO
	private static final int HILLS_COLOR = 0xFF0000;

	// TODO
	private static final int FOREST_COLOR = 0x00FF00;

	private static final int MOUNTAINS_COLOR = 0x303030;

	private static final int OCEAN_COLOR = 0x000058;

	private static final int[] CIV_COLOR = { 0, 0x2c7800, 0, 0, 0, 0x802014, 0x304cb0 };

	private Map map;

	private Player player;

	private Image mapImage;

	public short selectX;

	public short selectY;

	public PopupMap(final Player gamePlayer, final Map gameMap) {
		this.map = gameMap;
		this.player = gamePlayer;
		this.width = map.width + 4;
		this.height = map.height + MARGIN_PANEL_HEIGHT + 1;
		mapImage = Image.createImage(map.width, map.height);
		Graphics gMapImage = mapImage.getGraphics();
		for (short i = 0; i < map.width; i++)
			for (short j = 0; j < map.height; j++) {
				Tile tile = map.getTile(i, j);
				if (tile.image != null) {
					if (tile.city != null)
						gMapImage.setColor(CIV_COLOR[player.civilization]);
					else if (tile.terrain.type == TerrainType.HILL)
						gMapImage.setColor(HILLS_COLOR);
					else if (tile.terrain.type == TerrainType.FOREST)
						gMapImage.setColor(FOREST_COLOR);
					else if (tile.terrain.type == TerrainType.MOUNTAINS)
						gMapImage.setColor(MOUNTAINS_COLOR);
					else if (tile.terrain.type != TerrainType.OCEAN)
						gMapImage.setColor(TERRAIN_COLOR);
					else
						gMapImage.setColor(OCEAN_COLOR);

				} else
					gMapImage.setColor(32, 32, 32);
				gMapImage.fillRect(i, j, 1, 1);
			}
	}

	public void show(final int screenX, final int screenY) {
		this.x = screenX;
		this.y = screenY;
		this.isVisible = true;
		refresh();
	}

	public void refresh() {
		MapCanvasEngine.canvas.displayMap();
		Graphics graphics = MapCanvasEngine.canvas.graphics;
		graphics.setColor(128, 128, 128);
		graphics.fillRect(this.x, this.y, width, height);
		GraphicsCustomFont.drawString(graphics, "Map", this.x + 2, this.y + 3);
		showMap();
		showFocus();
		graphics.setColor(192, 192, 192);
		graphics.drawRect(this.x + 1, this.y + 15, width - 3, height - 15 - 2);
		MapCanvasEngine.canvas.repaint(this.x + 2, this.y + MARGIN_PANEL_HEIGHT - 1, map.width, map.height);
	}

	public void showMap() {
		Graphics graphics = MapCanvasEngine.canvas.graphics;
		graphics.drawImage(mapImage, this.x + 2, this.y + MARGIN_PANEL_HEIGHT - 1, Graphics.TOP | Graphics.LEFT);
	}

	public void showFocus() {
		Graphics graphics = MapCanvasEngine.canvas.graphics;
		graphics.setColor(255, 0, 0);
		if (MapCanvasEngine.canvas.dX >= map.width - MapCanvas.SCREEN_TILE_WIDTH) {
			int nx = MapCanvas.SCREEN_TILE_WIDTH - map.width + MapCanvasEngine.canvas.dX + 1;
			graphics.drawRect(this.x + 2 + MapCanvasEngine.canvas.dX, this.y + MARGIN_PANEL_HEIGHT - 1
					+ MapCanvasEngine.canvas.dY, map.width - MapCanvasEngine.canvas.dX, MapCanvas.SCREEN_TILE_HEIGHT);

			graphics.drawRect(this.x + 1, this.y + MARGIN_PANEL_HEIGHT - 1 + MapCanvasEngine.canvas.dY, nx,
					MapCanvas.SCREEN_TILE_HEIGHT);
		} else {
			graphics.drawRect(this.x + 2 + MapCanvasEngine.canvas.dX, this.y + MARGIN_PANEL_HEIGHT - 1
					+ MapCanvasEngine.canvas.dY, MapCanvas.SCREEN_TILE_WIDTH, MapCanvas.SCREEN_TILE_HEIGHT);
		}
	}

	public void keyPressed(final int key) {
		int action = MapCanvasEngine.canvas.getGameAction(key);
		if (action != 0)
			switch (action) {
				case Canvas.LEFT:
					MapCanvasEngine.canvas.dX = (short) ((MapCanvasEngine.canvas.dX - 1 + this.map.width) % this.map.width);
					refresh();
					break;
				case Canvas.RIGHT:
					MapCanvasEngine.canvas.dX = (short) ((MapCanvasEngine.canvas.dX + 1) % this.map.width);
					refresh();
					break;
				case Canvas.UP:
					if (MapCanvasEngine.canvas.dY > 0) {
						MapCanvasEngine.canvas.dY--;
						refresh();
					}
					break;
				case Canvas.DOWN:
					if (MapCanvasEngine.canvas.dY < map.height - MapCanvas.SCREEN_TILE_HEIGHT) {
						MapCanvasEngine.canvas.dY++;
						refresh();
					}
					break;
				case Canvas.FIRE:
					selectX = (short) ((MapCanvasEngine.canvas.dX + (MapCanvas.SCREEN_TILE_WIDTH / 2)) % map.width);
					selectY = (short) (MapCanvasEngine.canvas.dY + (MapCanvas.SCREEN_TILE_WIDTH / 2));
					this.hide();
					break;
				default:
					break;
			}
	}

}
